@{
    ViewBag.IncludePrism = true;
}

<div id="docs-content">
<markdown>

# Extending DotLiquid

Extending DotLiquid is very easy. If you do create useful filters or tags, please consider creating a pull request.

## Create your own filters

Creating filters is very easy. Filters are just methods which take one parameter and return a modified string.
You can use your own filters by passing an array of filter types to the `Render` call like this:

``` csharp
template.Render(new RenderParameters(CultureInfo.CurrentCulture)
{
	Filters = new[] { typeof(MyTextFilters), typeof(MyDateFilters) }
});
```

Example:

``` csharp
public static class TextFilter
{
    public static string Textilize(string input)
    {
        return TextileFormatter.FormatString(input);
    }
}

Template template = Template.Parse(" {{ '*hi*' | textilize }} ");
template.Render(new RenderParameters(CultureInfo.CurrentCulture)
{
	Filters = new[] { typeof(TextFilter) }
});
```

Alternatively, you can register your filters globally:

``` csharp
public static class TextFilter
{
    public static string Textilize(string input)
    {
        return TextileFormatter.FormatString(input);
    }
}

Template.RegisterFilter(typeof(TextFilter));
```

Once the filter is globally registered, you can simply use it. Filter names in liquid markup are lower case.

``` csharp
Template template = Template.Parse(" {{ '*hi*' | textilize }} ");
template.Render(); // => "<b>*hi*</b>"
```

A filter can access the current context if you add a Context object as the first argument to your filter method.  DotLiquid will automatically pass the current context to your filter:

``` csharp
public static String MyFilter(Context context, string input)
{
    //...
}
```

Filters also work from F#:

``` csharp
open DotLiquid

type TextFilter() =
    static member Textilize (input : string) =
        "<b>" + input + "</b>"

Template.RegisterFilter(TextFilter().GetType());
let template = Template.Parse(" {{ '*hi*' | textilize }} ");
printfn "%s" (template.Render()) // => "<b>*hi*</b>"
```

## Create your own tags

To create a new tag, simply inherit from `DotLiquid.Tag` and register your tag with `DotLiquid.Template`.

``` csharp
public class Random : DotLiquid.Tag
{
    private int _max;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        base.Initialize(tagName, markup, tokens);
        _max = Convert.ToInt32(markup);
    }

    public override void Render(Context context, TextWriter result)
    {
        result.Write(new Random().Next(_max).ToString());
    }
}

Template.RegisterTag<Random>("random");

Template template = Template.Parse(" {% random 5 %}");
template.Render(); // => "3"
```

### Create your own tag blocks

All tag blocks are parsed by DotLiquid. To create a new block,
you just have to inherit from `DotLiquid.Block` and register your block with `DotLiquid.Template`.

``` csharp
public class Random : DotLiquid.Block
{
    private int _max;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        base.Initialize(tagName, markup, tokens);
        _max = Convert.ToInt32(markup);
    }

    public override void Render(Context context, StreamWriter result)
    {
        if (new System.Random().Next(_max) == 0)
        base.Render(context, result);
    }
}

Template.RegisterTag<Random>("random");

string text = " {% random 5 %} wanna hear a joke? {% endrandom %} ";
Template template = Template.Parse(text);
template.Render(); // => In 20% of the cases, this will output "wanna hear a joke?"
```

### Adding custom operators

It is possible to add your own custom operators like this:

``` csharp
Condition.Operators["IsMultipleOf"] = (left, right) => (int)left % (int)right == 0;
```

And use it like this in ruby casing:

``` csharp
{% if 16 is_multiple_of 4 %} TRUE {% endif %}
```

Or like this in C# casing:

``` csharp
{% if 16 IsMultipleOf 4 %} TRUE {% endif %}
```

</markdown>
</div>